/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2009, Around(J2)ME				                                 **
 **   All rights reserved.                                                   **
 **                                                                          **
 **   This program and the accompanying materials are made available under   **
 **   the terms of the New BSD License which accompanies this    			 **
 **   distribution.											                 **
 **   A copy is found in the textfile LICENSE.txt							 **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Main developers:                                                       **
 **     Juri Strumpflohner		http://blog.js-development.com	             **
 **		Matthias Braunhofer		http://matthias.jimdo.com                    **
 **                                                                          **
 **  **********************************************************************  */

package org.aroundme.unitTools;

import java.util.ArrayList;
import java.util.Random;

import org.aroundme.model.Category;
import org.aroundme.model.CategoryName;
import org.aroundme.model.Comment;
import org.aroundme.model.DateManager;
import org.aroundme.model.Encrypter;
import org.aroundme.model.Location;
import org.aroundme.model.Place;
import org.aroundme.model.User;
import org.aroundme.utility.Constants;
import org.aroundme.utility.HibernateUtil;
import org.bouncycastle.util.encoders.Hex;
import org.hibernate.HibernateException;
import org.hibernate.Session;

public class XMLUnitTestUtils {
	private ArrayList<Place> dummyPlaces;
	private ArrayList<Location> dummyLocations; //needed for creating XML documents
	private ArrayList<User> dummyUsers;
	
	public XMLUnitTestUtils(){
		init();
	}
	
	public void init(){
		//create dummyuser
		dummyUsers = new ArrayList<User>();
		for(int i=0; i<3; i++){
			User us = new User();
			us.setLoginName("" + new UniqueIdGenerator().getUniqueId());
			us.setPassword("$abcdefg$" + us.getLoginName().substring(0,2));
			us.setFirstname("first " + i);
			us.setLastname("last " + i);
			us.setEmail("mail " + i);
			dummyUsers.add(us);
		}
		
		
//		create some places
		UniqueIdGenerator generator = new UniqueIdGenerator(); //to make title unique
		dummyPlaces = new ArrayList<Place>();
		for(int i=0; i<3; i++){
			Place p = new Place();
			p.setName("Place name n. " + i + generator.getUniqueId());
			p.setAddress("place address n. " + i + generator.getUniqueId());
			p.setCity("Place city n. " + i + generator.getUniqueId());
			p.setPhone("Place phone n. " + i + generator.getUniqueId());
			p.setUser(dummyUsers.get(i));
			p.setCreationDate(new DateManager().getCurrentDate());
			dummyPlaces.add(p);
		}
		
		dummyLocations = new ArrayList<Location>();
		for(int i=0; i<3; i++){
			Location l = new Location();
			l.setCellid(""+new UniqueIdGenerator().getUniqueId());
			l.setLat("" +new UniqueIdGenerator().getUniqueId());
			l.setLon("" +new UniqueIdGenerator().getUniqueId());
			dummyLocations.add(l);
		}
	}
	
	private int generateRandom(){
		Random r = new Random();
		int x = r.nextInt(3);
		return x;
	}
	
	private String createValidationPiece(){
		String validationData = "" +
		"<validationData>" +
		"<user>" + dummyUsers.get(0).getLoginName() + "</user>" +
		"<password>" + new String(Hex.encode(new Encrypter().encryptPassword(dummyUsers.get(0).getPassword()))) + "</password>" +
		"</validationData>";
		return validationData;
	}
	
	private String createValidationPiece(String user){
		String validationData = "" +
		"<validationData>" +
		"<user>" + user + "</user>" +
		"<password>" + new String(Hex.encode(new Encrypter().encryptPassword(dummyUsers.get(0).getPassword()))) + "</password>" +
		"</validationData>";
		return validationData;
	}
	
	/**
	 * Simulates a commit request from the client
	 * @param type
	 * @param locationType
	 * @return String representing an XMLCommitString
	 */
	public String createXMLCommitString(String type, String locationType, String[] categoryNames) {
		String xmlString = null;
		xmlString = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>"+
		"<root>" +
			"<type>" + type + "</type>" +
			createValidationPiece() +
			"<requestBody>";
		if(dummyPlaces!=null){
			for (Place place : dummyPlaces) {
				Location lTmp = null;
				if(locationType.equals("fixed")){
					lTmp = dummyLocations.get(1);
				}else{
					lTmp = dummyLocations.get(generateRandom());
				}
				xmlString += "<place>" +
								"<id>" + place.getId() + "</id>" +
								"<name>" + place.getName() + "</name>" +
								"<address>" + place.getAddress() + "</address>" +
								"<city>" + place.getCity() + "</city>" +
								"<phone>" + place.getPhone() + "</phone>" +
								"<user>" + place.getUser().getLoginName() + "</user>";
				xmlString +=    "<categories>";
									for (String catName : categoryNames) {
										xmlString +="<category>" + catName + "</category>";
									}
				xmlString +=    "</categories>";
				xmlString += 	"<location>" +
									"<cellid>" + lTmp.getCellid() + "</cellid>" +
									"<lat>" + lTmp.getLat() + "</lat>" + 
									"<lon>" + lTmp.getLon() + "</lon>" +
								"</location>" +
							 "</place>";
			}
		}
		xmlString += "</requestBody>" +
		"</root>";
		return xmlString;
	}
	
	public String createXMLCommitStringComment(String type, Comment comment){
		String xmlString = null;
		xmlString = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>"+
		"<root>" +
			"<type>" + type + "</type>" +
			createValidationPiece(comment.getUser().getLoginName()) +
			"<requestBody>";
//		for(int i=0; i<comments.length; i++){
			xmlString += "<comment>" +
							"<placeid>" + comment.getPlace().getId() +"</placeid>" +
							"<content>" + comment.getComment() + "</content>" +
							"</comment>";
			
//		}
		xmlString += "</requestBody>" +
		"</root>";
		return xmlString;
	}
	
	public String createXMLRetrieveString(String type, String requestParam, String searchQuery, String category, int begin, int end){
		String xmlString = null;
		xmlString = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>"+
		"<root>" +
			"<type>" + type + "</type>" +
			createValidationPiece() +
			"<requestBody>";
		
		xmlString += "<requestParam>" +
					requestParam +
					"</requestParam>";
		
		xmlString += "<beginData>" + begin + "</beginData>" +
					 "<dataAmount>" + end + "</dataAmount>";
		
		if(category != null && !category.equals(""))
			xmlString += "<category>" + category + "</category>";
		
		if(searchQuery!=null)
			xmlString += "<searchQuery>" + searchQuery + "</searchQuery>";
		
		xmlString += "<includeGlobal>true</includeGlobal>";
		
		xmlString += "<location>" +
					 "<cellid>" + dummyLocations.get(1).getCellid() + "</cellid>" +
					 "<lat>" + dummyLocations.get(1).getLat() + "</lat>" + 
					 "<lon>" + dummyLocations.get(1).getLon() + "</lon>" +
					 "</location>";
		
		xmlString += "</requestBody>" +
		"</root>";
		return xmlString;
	}
	
	public String createXMLDeleteString(Place place){
		String xmlString = null;
		xmlString = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>"+
		"<root>" +
			"<type>" + Constants.DELETE_PLACE + "</type>" +
			createValidationPiece() +
			"<requestBody>";
		
		xmlString += "<place>" +
						"<id>" + place.getId() + "</id>" +
						"<name>" + place.getName() + "</name>" +
						"<address>" + place.getAddress() + "</address>" +
						"<city>" + place.getCity() + "</city>" +
						"<phone>" + place.getPhone() + "</phone>";
		
		if(place.getCategories() != null && place.getCategories().size() > 0){
			xmlString += "<categories>";
			for (Category category : place.getCategories()) {
				xmlString += "<category>" + category.getName() + "</category>";
			}
			xmlString += "</categories>";
		}
		
		xmlString += 	"<user>" + place.getUser().getLoginName() + "</user>" +
					 "</place>";
		
		xmlString += "</requestBody>" +
		"</root>";
		return xmlString;
	}
	
	public void saveDummyUsersToDB() {
		Session s = HibernateUtil.getSessionFactory().getCurrentSession();
		s.beginTransaction();
		try{
			s.saveOrUpdate(dummyUsers.get(0));
			s.saveOrUpdate(dummyUsers.get(1));
			s.saveOrUpdate(dummyUsers.get(2));
			s.getTransaction().commit();
		}catch(HibernateException e){
			s.getTransaction().rollback();
			e.printStackTrace();
			throw e;
		}
	}
	
	public void saveDummyPlacesToDB(){
		//associate 1 Location and save to DB too
		Location l = dummyLocations.get(0);
		saveDummyLocation(l);
		
		Session s = HibernateUtil.getSessionFactory().getCurrentSession();
		s.beginTransaction();
		try{
			for (Place p : dummyPlaces) {
				if(p.getLocation() == null)
					p.setLocation(l);
				s.saveOrUpdate(p);
			}
			s.getTransaction().commit();
		}catch(HibernateException e){
			s.getTransaction().rollback();
			e.printStackTrace();
			throw e;
		}
	}
	
	public void saveDummyLocation(Location l){
		Session s = HibernateUtil.getSessionFactory().getCurrentSession();
		s.beginTransaction();
		try{
			s.saveOrUpdate(l);
			s.getTransaction().commit();
		}catch(HibernateException e){
			s.getTransaction().rollback();
			e.printStackTrace();
			throw e;
		}
	}

	public ArrayList<Place> getDummyPlaces() {
		return dummyPlaces;
	}

	public ArrayList<User> getDummyUsers() {
		return dummyUsers;
	}

	public ArrayList<Location> getDummyLocations() {
		return dummyLocations;
	}
	
}
